package com.bosch.in.jfree.chart;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Stroke;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.NumberFormat;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.BoxAndWhiskerToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.DatasetRenderingOrder;
import org.jfree.chart.renderer.category.BoxAndWhiskerRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.statistics.BoxAndWhiskerCategoryDataset;

/*
 * @author: liv1hc
 */
public class AbstractBoxPlotChart extends AbstractChart{
	
	//chart properties
	private String chartBackGroundColor 	= "#FFFFFF" ;
	private String plotBackGroundColor 		= "#FFFFFF" ;
	private String gridColor 				= "#000000" ;
	private String noDataExistMessage		= "No Data Exist";
	private String chartColor				= "#001558";
	private String chartColor2				= "#0069BD";
	private String labelColor				= "#0000FF";
	private String medianColor				= "#00B0F0";
	private String titleColor				= "#0000FF";
	private Stroke line2px					= (Stroke) new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
            															1.0f, new float[] {1.0f, 1.0f}, 0.0f
        																);
	private Stroke line15px					= (Stroke) new BasicStroke(1.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
			1.0f, new float[] {1.0f, 1.0f}, 0.0f
			);
	private int seriesIndex					= 0;
	
	private String title		= "";
	private int titleFontSize = 16;
	private String yAxisTitle = null;
	
	private static final Logger LOG = Logger.getLogger(AbstractBoxPlotChart.class);
	private int maxRange = 0;
	private final String toolTipFormat = "<table>" +
											"<tr><td colspan='2' align='center'>------------</td></tr>" +
											"<tr><td>Max</td><td>{5}</td></tr>" +
											"<tr><td>Q3</td><td>{7}</td></tr>" +
											"<tr><td>Median</td><td>{3}</td></tr>" +
											"<tr><td>Q1</td><td>{6}</td></tr>" +
											"<tr><td>Min</td><td>{4}</td></tr>"	+
											"<tr><td colspan='2' align='center'>------------</td></tr>" +
											"<tr><td>Total Items</td><td>{2}</td></tr>"	+
										 "</table>";
	@Override
	public String createChart(HttpServletRequest request,
			PrintWriter printWriter, int width, int height,
			String saveTofilepath) throws IOException {
		LOG.debug("<AbstractBoxPlotChart.createChart()");
		
		//chart
        JFreeChart chart = ChartFactory.createBoxAndWhiskerChart(title, "", "", (BoxAndWhiskerCategoryDataset) createDatasetLeftAxis(), false);
        chart.setBackgroundPaint(Color.decode(chartBackGroundColor));
		chart.setBorderVisible(true);
		chart.setBorderStroke(line2px);
		chart.getTitle().setFont(new Font(FONT_FAMILY, Font.BOLD, titleFontSize));
		chart.getTitle().setPaint(Color.decode(titleColor));
		chart.getTitle().setPadding(0.5, 0.2, 0.2, 0.2);

		//plot
        CategoryPlot plot = chart.getCategoryPlot();
       // plot.setOutlineVisible(false);		
		plot.setNoDataMessage(noDataExistMessage);		
		plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
		plot.setBackgroundPaint(Color.decode(plotBackGroundColor));
		plot.setRangeGridlinePaint(Color.decode(gridColor));
		
		// x line
		CategoryAxis xAxis = plot.getDomainAxis();
		xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);
		xAxis.setLabelFont(new Font(FONT_FAMILY, Font.BOLD, fontSize));
		xAxis.setLabelPaint(Color.decode(labelColor));
		
		//y line
		NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
		yAxis.setLabelFont(new Font(FONT_FAMILY, Font.BOLD, fontSize));
		yAxis.setLabelPaint(Color.decode(labelColor));
		yAxis.setNumberFormatOverride(getNumberFormatLeftYAxis());        
		yAxis.setAutoRangeIncludesZero(true);
		if (yAxisTitle != null)
		{
			yAxis.setLabel(yAxisTitle);
		}
        if (maxRange>0)
        {
        	yAxis.setUpperBound(this.maxRange);
        }
        
        //renderer
        BoxAndWhiskerRenderer renderer = (BoxAndWhiskerRenderer) plot.getRenderer();
        renderer.setFillBox(false);
        renderer.setArtifactPaint(Color.decode(medianColor));
        renderer.setBaseFillPaint(Color.decode(chartColor));
        renderer.setSeriesOutlinePaint(seriesIndex, Color.decode(chartColor2));
        renderer.setSeriesOutlineStroke(seriesIndex, line15px);
        renderer.setSeriesPaint(seriesIndex, Color.decode(chartColor));
        renderer.setSeriesStroke(seriesIndex, line15px);
        renderer.setMaximumBarWidth(0.1);
        // hide mean value
        renderer.setMeanVisible(false);
        renderer.setBaseToolTipGenerator(new BoxAndWhiskerToolTipGenerator(toolTipFormat,NumberFormat.getInstance()));
        
        //chart panel
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(width, height));
        chartPanel.setDisplayToolTips(true);

		//set the filepath to save the image
		setFilename(saveTofilepath);
		String filename = setImage(request, printWriter, width, height, chart);
		
		printWriter.flush();
		LOG.debug("<AbstractBoxPlotChart.createChart()>");
		return filename;
	}

	@Override
	public CategoryDataset createDatasetLeftAxis() {
		return null;
	}

	public String getChartBackGroundColor() {
		return chartBackGroundColor;
	}

	public void setChartBackGroundColor(String chartBackGroundColor) {
		this.chartBackGroundColor = chartBackGroundColor;
	}

	public String getPlotBackGroundColor() {
		return plotBackGroundColor;
	}

	public void setPlotBackGroundColor(String plotBackGroundColor) {
		this.plotBackGroundColor = plotBackGroundColor;
	}

	public String getGridColor() {
		return gridColor;
	}

	public void setGridColor(String gridColor) {
		this.gridColor = gridColor;
	}

	public String getNoDataExistMessage() {
		return noDataExistMessage;
	}

	public void setNoDataExistMessage(String noDataExistMessage) {
		this.noDataExistMessage = noDataExistMessage;
	}

	public String getChartColor() {
		return chartColor;
	}

	public void setChartColor(String chartColor) {
		this.chartColor = chartColor;
	}

	public String getChartColor2() {
		return chartColor2;
	}

	public void setChartColor2(String chartColor2) {
		this.chartColor2 = chartColor2;
	}

	public String getLabelColor() {
		return labelColor;
	}

	public void setLabelColor(String labelColor) {
		this.labelColor = labelColor;
	}

	public String getMedianColor() {
		return medianColor;
	}

	public void setMedianColor(String medianColor) {
		this.medianColor = medianColor;
	}

	public String getTitleColor() {
		return titleColor;
	}

	public void setTitleColor(String titleColor) {
		this.titleColor = titleColor;
	}

	public Stroke getLine2px() {
		return line2px;
	}

	public void setLine2px(Stroke line2px) {
		this.line2px = line2px;
	}

	public Stroke getLine15px() {
		return line15px;
	}

	public void setLine15px(Stroke line15px) {
		this.line15px = line15px;
	}

	public int getSeriesIndex() {
		return seriesIndex;
	}

	public void setSeriesIndex(int seriesIndex) {
		this.seriesIndex = seriesIndex;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public int getTitleFontSize() {
		return titleFontSize;
	}

	public void setTitleFontSize(int titleFontSize) {
		this.titleFontSize = titleFontSize;
	}

	public String getyAxisTitle() {
		return yAxisTitle;
	}

	public void setyAxisTitle(String yAxisTitle) {
		this.yAxisTitle = yAxisTitle;
	}

	public int getMaxRange() {
		return maxRange;
	}

	public void setMaxRange(int maxRange) {
		this.maxRange = maxRange;
	}

}
